import React, {PureComponent} from "react";
import {connect} from "react-redux";
import {Button, Form, Icon, Input, InputNumber, notification, Popconfirm, Select, Table, Upload} from "antd";
import {tableProps} from "../../lib/ui";
import {delVehiclePrice, getVehicleFeesByClientId, importVehicle, updateVehicleFees} from "./actions";
import {getPrincipal} from "../../lib/identity";
import VehicleFeeFilter from "./VehicleFeeFilter";

const {Option, OptGroup} = Select;
const EditableContext = React.createContext();

const EditableRow = ({form, index, ...props}) => (
    <EditableContext.Provider value={form}>
        <tr {...props} />
    </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
    state = {
        editing: false,
    };

    toggleEdit = () => {
        const editing = !this.state.editing;
        this.setState({editing}, () => {
            if (editing) {
                this.input.focus();
            }
        });
    };

    save = e => {
        const {record, handleSave} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            handleSave({...record, ...values});
        });
    };

    changeLine = line => {
        const {record, handleSave} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[line.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            const places = line.split("-");
            values.startPlace = places[0];
            values.endPlace = places[1];
            values.line = line;
            handleSave({...record, ...values});
        });
    };

    selectVehicle = vehicleName => {
        const {record, handleSave} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[vehicleName]) {
                return;
            }
            this.toggleEdit();
            values.name = vehicleName;
            handleSave({...record, ...values});
        });
    };

    saveCurrency = e => {
        const {record, handleSave} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e]) {
                return;
            }
            this.toggleEdit();
            values.currency = e;
            handleSave({...record, ...values});
        });
    };

    renderCell = form => {
        this.form = form;
        const {children, dataIndex, record, inputType, options = [], placeholder} = this.props;
        const {editing} = this.state;
        let column;
        if (inputType === "number") {
            column = <InputNumber ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save}/>;
        } else if (inputType === "selectVehicle") {
            column = <Select placeholder={placeholder} ref={node => (this.input = node)} style={{width: 150}}
                             onChange={this.selectVehicle} allowClear={true} showSearch={true}>
                {options.map((item, index) => (
                    <Option key={index}
                            value={item.name}>
                        {item.name}
                    </Option>
                ))}
            </Select>;
        } else if (inputType === "selectLine") {
            column = <Select placeholder={placeholder} ref={node => (this.input = node)} style={{width: 300}}
                             onChange={this.changeLine} allowClear={true} showSearch={true}>
                {options.map((item, index) => (
                    <OptGroup key={Math.random().toString()} label={item.name}>
                        {
                            item.data.map((dataItem, data_item_index) => (
                                <Option
                                    key={Math.random().toString()}
                                    value={dataItem.originPlace + "-" + dataItem.destPlace}>
                                    {dataItem.originPlace + "-" + dataItem.destPlace}
                                </Option>
                            ))
                        }
                    </OptGroup>
                ))}
            </Select>;
        } else {
            column = <Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save}/>;
        }
        return editing ? (
            <Form.Item style={{margin: 0}}>
                {form.getFieldDecorator(dataIndex, {
                    initialValue: record[dataIndex],
                })(column)}
            </Form.Item>
        ) : (
            <div
                className="editable-cell-value-wrap"
                style={{paddingRight: 24}}
                onClick={this.toggleEdit}
            >
                {children}
            </div>
        );
    };

    render() {
        const {
            editable,
            dataIndex,
            title,
            record,
            index,
            inputType,
            options,
            placeholder,
            handleSave,
            children,
            valueField,
            labelField,
            ...restProps
        } = this.props;
        return (
            <td {...restProps}>
                {editable ? (
                    <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
                ) : (
                    children
                )}
            </td>
        );
    }
}

class VehicleFeeModal extends PureComponent {

    state = {
        importLoading: false
    };

    handleSave = values => {
        const {dispatch, vehiclePrices} = this.props;
        const found = vehiclePrices.find(vehicle => vehicle.id === values.id);
        if (values.startPlace) {
            found.startPlace = values.startPlace;
        }
        if (values.endPlace) {
            found.endPlace = values.endPlace;
        }
        if (values.amount) {
            found.amount = values.amount;
        }
        if (values.name) {
            found.name = values.name;
        }
        dispatch(updateVehicleFees(vehiclePrices));
    };

    handleShowCreate = () => {
        const {dispatch, vehiclePrices} = this.props;
        vehiclePrices.splice(0, 0, {
            "id": Math.random().toString(),
            "userName": getPrincipal().fullName,
            "currency": "人民币",
            "amount": 0
        });
        dispatch(updateVehicleFees(vehiclePrices));
    };

    handleDeleteFee = id => {
        const {dispatch, vehiclePrices} = this.props;
        const newVehiclePrices = [];
        vehiclePrices.forEach(item => {
            if (item.id !== id) {
                newVehiclePrices.push(item);
            }
        });
        dispatch(updateVehicleFees(newVehiclePrices));
        if (id && id.indexOf("VP") >= 0) {
            dispatch(delVehiclePrice(id));
        }
    };

    customRequest = (options) => {
        const {dispatch, model} = this.props;
        this.setState({importLoading: true});
        notification.info({
            message: '正在导入'
        });
        dispatch(importVehicle({
            file: options.file,
            belongId: model.id,
        })).then(() => {
            this.setState({importLoading: false});
            notification.success({
                message: '导入成功'
            });
            dispatch(getVehicleFeesByClientId({"ownerId": model.id}));
        });
    };
    uploadProps = {
        showUploadList: false,
        name: 'file',
        accept: '.xls, .xlsx, .csv',
        customRequest: this.customRequest
    };

    render() {
        const {vehiclePrices = [], loading, lines = [], vehicles = []} = this.props;
        const lineDataList = [];
        const businessTypeList = [];
        lines.forEach(line => {
            if (businessTypeList.indexOf(line.businessType) < 0 && line.businessType !== "中欧铁路") {
                businessTypeList.push(line.businessType);
            }
        });
        businessTypeList.forEach(item => {
            const lineDataItem = {"name": item, "data": []};
            lines.forEach(line => {
                if (line.businessType === item) {
                    lineDataItem.data.push({...line});
                }
            });
            lineDataList.push(lineDataItem);
        });
        vehiclePrices.forEach(item => {
            if (item.startPlace && item.endPlace) {
                item.line = item.startPlace + '-' + item.endPlace;
            }
        });
        const columns = [
            {
                title: "车型",
                dataIndex: "name",
                editable: true,
                inputType: "selectVehicle",
                options: vehicles,
                placeholder: "请选择车型",
                width: "150px",
            }, {
                title: "线路",
                dataIndex: "line",
                editable: true,
                inputType: "selectLine",
                options: lineDataList,
                placeholder: "请选择线路",
                width: "300px"
            }
            , {
                title: "币种",
                dataIndex: "currency",
                width: "150px",
                render: () => ("人民币")
            }, {
                title: "运输费",
                dataIndex: "amount",
                width: "150px",
                editable: true,
                inputType: "number"
            }, {
                title: '功能',
                dataIndex: '',
                key: 'x',
                width: "150px",
                render: (text, record) => <div className="actions">
                    <Popconfirm title="是否删除费用?" okText="是" cancelText="否"
                                onConfirm={() => this.handleDeleteFee(record.id)}>
                        <a>删除</a>
                    </Popconfirm></div>

            }, {
                title: "",
                dataIndex: ""
            }
        ];
        const components = {
            body: {
                row: EditableFormRow,
                cell: EditableCell,
            },
        };
        const editColumns = columns.map(col => {
            if (!col.editable) {
                return col;
            }
            return {
                ...col,
                onCell: record => ({
                    record,
                    editable: col.editable,
                    dataIndex: col.dataIndex,
                    title: col.title,
                    inputType: col.inputType,
                    options: col.options,
                    handleSave: this.handleSave,
                }),
            };
        });
        return (

            <div>
                <VehicleFeeFilter/>
                <div className="actions">
                    <Button onClick={this.handleShowCreate}><Icon type="plus"/>新增</Button>
                    <Button href="/static/车型费用导入模板.xlsx" target="_blank">下载导入模板</Button>
                    <Upload {...this.uploadProps}>
                        <Button disabled={this.state.importLoading}>
                            <Icon type="upload"/> 导入
                        </Button>
                    </Upload>
                </div>
                <Table
                    {...tableProps}
                    columns={editColumns}
                    dataSource={vehiclePrices}
                    components={components}
                    loading={loading}
                    rowClassName={() => 'editable-row'}
                />
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        ...state.client.clientVehicleFee,
        lines: state.line.list.dataSource,
        vehicles: state.vehicle.list.dataSource,
        model: state.client.modify.model
    };
};

export default connect(mapStateToProps)(VehicleFeeModal);
